package com.jmectf.net;

import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import com.jme.math.Vector3f;
import com.jmectf.net.console.ServerThread;
import com.jmectf.net.message.ServerExitMessage;
import com.jmectf.net.message.Synch3DMessage;

public class BattleServer {

	PlayerData data;
	ServerSocket server;
	ServerThread t;
	Timer timer;
	int clients = 0;
	ArrayList<Vector3f> positionsToSend;
	
	public BattleServer(ServerThread t) {
		data = new PlayerData();
		this.t = t;
	}

	public void run() throws IOException {
		timer = new Timer();
		t.update("Starting server...");
		server = new ServerSocket(4242, 20);
		t.update("Server online. Waiting for connections...");
		timer.scheduleAtFixedRate(new TimerTask() {
			public void run() {
				try {
					processConnections();
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
				catch (IOException e) {
					e.printStackTrace();
				}
			}
		}, 0, 50);
		while(true)
			waitForConnection();
	}

	public void close() throws IOException {
		ServerExitMessage exitMessage = new ServerExitMessage();
		for(int i = 0; i < data.getConnections().size(); i++) {
			data.getOutputStreams().get(i).writeObject(exitMessage);
			data.getOutputStreams().get(i).flush();	
		}
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		for(Socket s : data.getConnections()) {
			s.close();
		}
		t.update("Server offline.");
	}

	private void waitForConnection() throws IOException{
		data.getConnections().add(server.accept());
		data.getInputStreams().add(new ObjectInputStream(data.getConnections().getLast().getInputStream()));
		data.getOutputStreams().add(new ObjectOutputStream(data.getConnections().getLast().getOutputStream()));
		clients = data.getConnections().size();
		t.update("\nClient " + clients + " (" + data.getConnections().getLast().getInetAddress().toString() + ") connected to server.");
	}

	private synchronized void processConnections() throws ClassNotFoundException, IOException {
		for(int i = 0; i < data.getConnections().size(); i++) {
			Object message;
			try {
				if(data.getInputStreams().size() <= i) {
					System.out.println("phail");
					continue;
				}
				message = data.getInputStreams().get(i).readObject();
				if(message instanceof Synch3DMessage) {
					Synch3DMessage m = (Synch3DMessage) message;
					String[] me = m.getPosition().split(",");
					Vector3f temp = new Vector3f(Float.parseFloat(me[0]), Float.parseFloat(me[1]), Float.parseFloat(me[2]));
					if(data.getPositions().size() <= i)
						data.getPositions().add(i, temp);
					else
						data.getPositions().set(i, temp);
					t.update(data);

				}
			} catch(EOFException e) {
				t.update("[client " + i + "] quit.");
				data.getConnections().remove(i);
				data.getInputStreams().remove(i);
				data.getOutputStreams().remove(i);
				continue;
			} catch(SocketException e) {
				t.update("[client " + i + "] quit.");
				data.getConnections().remove(i);
				data.getInputStreams().remove(i);
				data.getOutputStreams().remove(i);
				continue;
			}
		}
	}

}
